﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;

//---------------------------------------------------------------------------------//

//--------------------------------增量频繁项集挖掘算法-----------------------------//

//---------------------------------------------------------------------------------//



namespace LJTest
{
    class DataMining
    {
        ArrayList FrequencyFileTEMP;
        ArrayList FrequencyFileTEMPno;
        ArrayList frequencyfile;//原频繁项集
        ArrayList frequencyno;//原频繁项集对应的支持度
        ArrayList frenum;
        ArrayList frequency;//新增的频繁项集
        ArrayList fre_no;//新增的频繁项集对应的支持度
        ArrayList addtionRules=new ArrayList();
        ArrayList rules;//新增的关联规则

        private double support;

        public double Support
        {
            get { return support; }
            set { support = value; }
        }
        private double mf;

        public double Mf
        {
            get { return mf; }
            set { mf = value; }
        }

        private int checkRownum()//临时事务的条数
        {
            int rownum = 0;
            if (File.Exists(Common.TRANSACTION_FILE_TEMP))
            {
                try
                {
                    String InLine;
                 
                    using (StreamReader sr = new StreamReader(Common.TRANSACTION_FILE_TEMP, Encoding.GetEncoding("gb2312")))
                    {
                        while ((InLine = sr.ReadLine()) != null)
                        {
                            rownum++;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("临时事务的条数:" + ex.Message);
                }
            }
            return rownum;
        }
        public  void minging()
        {
            Console.WriteLine("增量挖掘开始");
            if (checkRownum() >= 10)
            {
                addtionalFrequency(support);//频繁项集
                //File.WriteAllText(Common.TRANSACTION_FILE_TEMP, "");//清空transaction_temp
                readFREQUENCY_FILE_TEMP();
                mingfrequency(support);//增量频繁项集
                writeAddtionalFrequency(Common.FREQUENCY_FILE_PATH);
                getAddtionRalatedRules(mf);//增量关联规则
                File.WriteAllText(Common.TRANSACTION_FILE_TEMP, "");//清空transaction_temp
                File.WriteAllText(Common.FREQUENCY_FILE_TEMP, "");
            }
            else
            {
                Console.WriteLine("事务集过少");
            }
            Console.WriteLine("增量挖掘结束");
        }

        public void mingfrequency(double support)
        {
            Console.WriteLine("计算增量频繁项集开始");
            //..............在此执行增量事务数据集挖掘工作
            isInFrequencyFile();
            frequency = new ArrayList();
            fre_no=new ArrayList();
            ArrayList transactionOld = Transaction.getTransactions(Common.TRANSACTION_FILE_PATH);
            ArrayList transactionTemp = Transaction.getTransactions(Common.TRANSACTION_FILE_TEMP);
            ArrayList al = countFrequencyITEMs(transactionOld);
            int i = 0;
            int sum = (transactionOld.Count + transactionTemp.Count) / 2;
            int x = transactionTemp.Count / 2;
            int y = transactionOld.Count / 2;
            int n = 0, m = 0;
            foreach (ArrayList l in FrequencyFileTEMP)
            {
                if (((Convert.ToDouble(FrequencyFileTEMPno[i]) + Convert.ToDouble(al[i]))) / (double)sum >= support)
                {
                    frequency.Add(l);
                    fre_no.Add(((Convert.ToDouble(FrequencyFileTEMPno[i]) + Convert.ToDouble(al[i]))) / (double)sum);
                    n++;
                }
               if ((Convert.ToDouble(FrequencyFileTEMPno[i]) / (double)x - Convert.ToDouble(al[i]) / (double)y) >= support)
               {
                   frequency.Add(l);
                   fre_no.Add((Convert.ToDouble(FrequencyFileTEMPno[i]) / (double)x - Convert.ToDouble(al[i]) / (double)y));
                   m++;
                }
                   
                i++;

            }
            Console.WriteLine("n=:{0}", n);
            Console.WriteLine("m=:{0}", m);
            Console.WriteLine("计算增量频繁项集结束");
        }



        //将增量的频繁项集写入到原频繁项集文件里
        public void writeAddtionalFrequency(string saveFileName)
        {
            int i, j = 0;
            string[] data = new string[frequency.Count];
            foreach (ArrayList Cdata in frequency)
            {
                data[j] = fre_no[j] + "|";
                for (i = 0; i < Cdata.Count; i++)
                {
                    //Console.Write("<{0}>\t", Cdata[i]);
                    data[j] += (i == (Cdata.Count - 1) ? Cdata[i] : Cdata[i] + ",");
                }
                data[j] += "\n";
                j++;
               
            }
            //File.WriteAllLines(Common.FREQUENCY_FILE_PATH,data);
            StreamWriter transtreamwriter = new StreamWriter(saveFileName, true);
            for (int k = 0; k < data.Length; k++)
            {
                transtreamwriter.WriteLine(data[k]);
            }
            transtreamwriter.Close();
        }



        //挖掘增量频繁项集
        public  void addtionalFrequency(double  support)
        {
            //int support = int.Parse(textBoxSupport.Text.Trim());
            //int deep = int.Parse(textBoxDeep.Text.Trim());
            Apriori.Test(support, Common.TRANSACTION_FILE_TEMP, Common.FREQUENCY_FILE_TEMP);
        }

        //删除频繁项集里面包含增量频繁项集的项
        public void isInFrequencyFile()
        {
            ArrayList FrequencyFileTEMPcopy = new ArrayList();
            ArrayList sub;
            foreach (ArrayList t in FrequencyFileTEMP)
            {
                sub = new ArrayList();
                foreach (string ss in t)
                {
                    sub.Add(ss);
                }
                FrequencyFileTEMPcopy.Add(sub);
            }//深度拷贝
            ArrayList FrequencyFileTEMPnocopy = (ArrayList)FrequencyFileTEMPno.Clone();
            FrequencyFileTEMP.Clear();
            FrequencyFileTEMPno.Clear();

            int index = 0;
            foreach (ArrayList frequency in FrequencyFileTEMPcopy)
            {
                bool isExist = false;
                foreach (ArrayList fre in frequencyfile)
                {
                    if (fre.Contains((string)frequency[0]))
                    {
                        isExist = true;
                       
                    }    
                }
                if (!isExist)
                {
                    FrequencyFileTEMP.Add(frequency);
                    FrequencyFileTEMPno.Add(FrequencyFileTEMPnocopy[index]);
                }
                index++;
            }
        }

       
       
        //
       public void readFREQUENCY_FILE_TEMP()
       {
           //读增量频繁项集
           if(File.Exists(Common.FREQUENCY_FILE_TEMP))
           {
                 try
                {
                    String InLine;
                   FrequencyFileTEMP = new ArrayList();
                   FrequencyFileTEMPno= new ArrayList();
                    ArrayList sub = new ArrayList();

                    using (StreamReader sr = new StreamReader(Common.FREQUENCY_FILE_TEMP, Encoding.GetEncoding("gb2312")))
                    {
                        while ((InLine = sr.ReadLine()) != null)
                        {
                           
                            if (InLine != null && !InLine.Equals(""))
                            {
                                int firstIndex = InLine.IndexOf("|");

                                 FrequencyFileTEMPno.Add(InLine.Substring(0, firstIndex)); //箭头前面的一个数字
                                string str = InLine.Substring(firstIndex + 1, InLine.Length - 1 - firstIndex);
                                foreach (string k in str.Split(','))
                                {
                                    sub.Add(k);
                                }
                                 FrequencyFileTEMP.Add(sub);
                                sub = new ArrayList();
                            }

                        }
                    }

                }
                catch (Exception ex)
                {
                    Console.WriteLine("读取增量频繁项集中的记录出错：" + ex.Message);
                }
           }
           
           //读频繁项集
           if (File.Exists(Common.FREQUENCY_FILE_PATH))
           {
               try
               {
                   String InLine;
                   frequencyfile = new ArrayList();
                   frequencyno = new ArrayList();
                   ArrayList sub = new ArrayList();

                   using (StreamReader sr = new StreamReader(Common.FREQUENCY_FILE_PATH, Encoding.GetEncoding("gb2312")))
                   {
                       while ((InLine = sr.ReadLine()) != null)
                       {
                           //Console.WriteLine(InLine);
                           if (InLine != null && !InLine.Equals(""))
                           {
                               int firstIndex = InLine.IndexOf("|");

                               frequencyno.Add(InLine.Substring(0, firstIndex)); //箭头前面的一个数字
                               string str = InLine.Substring(firstIndex + 1, InLine.Length - 1 - firstIndex);
                               foreach (string k in str.Split(','))
                               {
                                   sub.Add(k);
                               }
                               frequencyfile.Add(sub);
                               sub = new ArrayList();
                           }

                       }
                   }
               
               }
               catch (Exception ex)
               {
                   Console.WriteLine("读取频繁项集中的记录出错：" + ex.Message);
               }
           }

       }

       public void  getAddtionRalatedRules(double mf)
       {
           Console.WriteLine("增量关联规则挖掘开始");
           ArrayList I = new ArrayList();//what is this?
           ArrayList Ino = new ArrayList(); //
           //int num = 0;
           int n = 0;
           rules = new ArrayList();

           
           foreach (ArrayList fre in frequency)
           {

               if (fre.Count == 1)
               {

                   I.Add(fre[0]);
                   Ino.Add(fre_no[n]);
                   if (Convert.ToInt32(fre_no[n]) >= mf)
                   {
                       //ArrayList cachelist = Common.readCacheDataFromDB(Common.CACHE_TABLE);
                       if (!Common.checkInCache(fre[0].ToString()))
                       {
                           rules.Add(fre_no[n] + "|->" + fre[0]);
                           //写入缓存中：(要删除掉与缓存中数据相同的项）？？？

                           string sql = "insert into cache values('" + DateTime.Now.ToString("s") + "' ,'" + DateTime.Now.ToString("s") + "','" + fre[0] + "','" + Common.CaculateDataSize(fre[0].ToString()) + "','" + "N" + "')";
                           SQLiteHelper.ExecuteSql(sql);
                       }
                   }

               }
               else
               {
                   foreach (string l in fre)
                   {
                       //Console.WriteLine("I.Contains(" + l + ")=" + I.Contains(l));
                       double x = calculate(Convert.ToDouble (fre_no[n]), I, Ino, l);
                       if (I.Contains(l) && (x >= Convert.ToDouble(mf)))
                       {
                           string str = "";
                           //int sindex = 0;
                           foreach (string s in fre)
                           {
                               str += (s.Equals(l) ? "" : s + ",");

                           }
                           str = str.Substring(0, str.Length - 1);
                           rules.Add(x + "|" + l + "->" + str);
                           //I.Remove(l);
                       }
                   }
                   

               }
              
               n++;


           }
           StreamWriter transtreamwriter = new StreamWriter(Common.RULE_FILE_PATH, true);
           foreach (string str in rules)
           {
               transtreamwriter.WriteLine(str);
           }
           transtreamwriter.Close();
           Console.WriteLine("增加了{0}条关联规则",rules.Count);
           Console.WriteLine("增量关联规则挖掘结束");
           //StreamWriter transtreamwriter = new StreamWriter(Common.RULE_FILE_PATH, true);
           //foreach (string str in rules)
           //{
           //    transtreamwriter.WriteLine(str);
           //}
           //transtreamwriter.Close();
          

       }

   

       public static double calculate(double   support, ArrayList fi, ArrayList fi_no, string item)
       {
           double x = 0;
           int index = 0;
           foreach (string str in fi)
           {
               if (str.Equals(item))
               {
                   break;
               }
               else
               {
                   index++;
               }
           }
           if (index >= fi.Count) return x;
           x = Convert.ToDouble(support / Convert.ToDouble(fi_no[index]));
           // x = Convert.ToDecimal( Convert.ToInt32(fi_no[index]) /support);
           //Console.WriteLine("x=" + x);
           return x;



       }



       //统计FREQUENCY_FILE_TEMP每个项在原事务数据库中的计数
        public ArrayList  countFrequencyITEMs(ArrayList  TRANSACTION_FILE)
        {
            ArrayList result = new ArrayList();
            string[] transaction= new string[TRANSACTION_FILE.Count];
            int index = 0;
            foreach (ArrayList trandata in TRANSACTION_FILE)
            {
                foreach (string str in trandata)
                {
                    transaction[index] += str;
                }
                index++;
            }

            foreach (ArrayList subdata in FrequencyFileTEMP)
            {
                string substr = "";
                foreach (string sub in subdata)
                {
                    substr += sub;
                }
                int totalCount = 0;
                for(int i=0;i<transaction.Length;i++)
                {
                    int count = countnum(transaction[i], substr);
                    if (count > 0) totalCount++;
                }
                result.Add(totalCount);
            }
            return result;

          }

        private int countnum(string text1, string text2) //求一个字符串text2在另一个字符串text1中出现的次数
        {
            int total = 0;
            int loact = text1.IndexOf(text2);
            while (loact != -1)
            {
                int loc = text1.IndexOf(text2) + text2.Length;
                int len = text1.Length - loc;
                if (loc != -1)
                {
                    text1 = text1.Substring(loc, len);
                }
                loact = text1.IndexOf(text2);
                total++;
            }
            return total;
        }
     } 

  }
        
   
